package com.smartlink.app.face;

import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Process;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast;

import com.iflytek.cloud.FaceDetector;
import com.iflytek.cloud.util.Accelerometer;
import com.smartlink.app.R;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 离线视频流检测示例
 * 该业务仅支持离线人脸检测SDK，请开发者前往<a href="http://www.xfyun.cn/">讯飞语音云</a>SDK下载界面，下载对应离线SDK
 */
public class VideoDemo extends Activity {
    //人脸验证类型
    public static final int FACE_VERIFY = 1;

    //人脸验证返回类型
    public static final int FACE_VERIFY_RESULT = 30;


    private final static String TAG = VideoDemo.class.getSimpleName();
    private SurfaceView mPreviewSurface;
    private SurfaceView mFaceSurface;
    private Camera mCamera;
    private int mCameraId = CameraInfo.CAMERA_FACING_FRONT;
    // Camera nv21格式预览帧的尺寸，默认设置640*480
    private int PREVIEW_WIDTH = 640;
    private int PREVIEW_HEIGHT = 480;
    // 预览帧数据存储数组和缓存数组
    private byte[] nv21;
    private byte[] buffer;
    // 缩放矩阵
    private Matrix mScaleMatrix = new Matrix();
    // 加速度感应器，用于获取手机的朝向
    private Accelerometer mAcc;
    // FaceDetector对象，集成了离线人脸识别：人脸检测、视频流检测功能
    private FaceDetector mFaceDetector;
    private boolean mStopTrack;
    private Toast mToast;
    private long mLastClickTime;
    private int isAlign = 0;
    private boolean safeToTakePicture = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_demo);
        initUI();
        nv21 = new byte[PREVIEW_WIDTH * PREVIEW_HEIGHT * 2];
        buffer = new byte[PREVIEW_WIDTH * PREVIEW_HEIGHT * 2];
        mAcc = new Accelerometer(VideoDemo.this);
        mFaceDetector = FaceDetector.createDetector(VideoDemo.this, null);
        takePhoto();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                VideoDemo.this.finish();
            }
        }, 10000);
    }


    private Callback mPreviewCallback = new Callback() {

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            closeCamera();
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            openCamera();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int
                width,
                                   int height) {
            mScaleMatrix.setScale(width / (float) PREVIEW_HEIGHT, height /
                    (float) PREVIEW_WIDTH);
        }
    };

    private void setSurfaceSize() {
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);

        int width = metrics.widthPixels;
        int height = (int) (width * PREVIEW_WIDTH / (float) PREVIEW_HEIGHT);
        LayoutParams params = new LayoutParams(width,
                height);
        params.addRule(RelativeLayout.ALIGN_PARENT_TOP);

        mPreviewSurface.setLayoutParams(params);
        mFaceSurface.setLayoutParams(params);
    }

    @SuppressLint("ShowToast")
    @SuppressWarnings("deprecation")
    private void initUI() {
        mPreviewSurface = (SurfaceView) findViewById(R.id.sfv_preview);
        mFaceSurface = (SurfaceView) findViewById(R.id.sfv_face);

        mPreviewSurface.getHolder().addCallback(mPreviewCallback);
        mPreviewSurface.getHolder().setType
                (SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mFaceSurface.setZOrderOnTop(true);
        mFaceSurface.getHolder().setFormat(PixelFormat.TRANSLUCENT);

        // 点击SurfaceView，切换摄相头
        mFaceSurface.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 只有一个摄相头，不支持切换
                if (Camera.getNumberOfCameras() == 1) {
                    showTip("只有后置摄像头，不能切换");
                    return;
                }
                closeCamera();
                if (CameraInfo.CAMERA_FACING_FRONT == mCameraId) {
                    mCameraId = CameraInfo.CAMERA_FACING_BACK;
                } else {
                    mCameraId = CameraInfo.CAMERA_FACING_FRONT;
                }
                openCamera();
            }
        });

        // 长按SurfaceView 500ms后松开，摄相头聚集
        mFaceSurface.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mLastClickTime = System.currentTimeMillis
                                ();
                        break;
                    case MotionEvent.ACTION_UP:
                        if (System.currentTimeMillis() -
                                mLastClickTime > 500) {
                            mCamera.autoFocus(null);
                            return true;
                        }
                        break;

                    default:
                        break;
                }
                return false;
            }
        });

        RadioGroup alignGruop = (RadioGroup) findViewById(R.id.align_mode);
        alignGruop.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup arg0, int arg1) {
                switch (arg1) {
                    case R.id.detect:
                        isAlign = 0;
                        break;
                    case R.id.align:
                        isAlign = 1;
                        break;
                    default:
                        break;
                }
            }
        });

        setSurfaceSize();
        mToast = Toast.makeText(VideoDemo.this, "", Toast.LENGTH_SHORT);
    }

    private void openCamera() {
        if (null != mCamera) {
            return;
        }

        if (!checkCameraPermission()) {
            showTip("摄像头权限未打开，请打开后再试");
            mStopTrack = true;
            return;
        }

        // 只有一个摄相头，打开后置
        if (Camera.getNumberOfCameras() == 1) {
            mCameraId = CameraInfo.CAMERA_FACING_BACK;
        }

        try {
            mCamera = Camera.open(mCameraId);
            if (CameraInfo.CAMERA_FACING_FRONT == mCameraId) {
                showTip("前置摄像头已开启，点击可切换");
            } else {
                showTip("后置摄像头已开启，点击可切换");
            }
        } catch (Exception e) {
            e.printStackTrace();
            closeCamera();
            return;
        }

        Parameters params = mCamera.getParameters();
        params.setPreviewFormat(ImageFormat.NV21);
        params.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
        mCamera.setParameters(params);

        // 设置显示的偏转角度，大部分机器是顺时针90度，某些机器需要按情况设置
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewCallback(new PreviewCallback() {

            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                System.arraycopy(data, 0, nv21, 0, data.length);
            }
        });

        try {
            mCamera.setPreviewDisplay(mPreviewSurface.getHolder());
            mCamera.startPreview();
            safeToTakePicture = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void closeCamera() {
        if (null != mCamera) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    private boolean checkCameraPermission() {
        int status = checkPermission(permission.CAMERA, Process.myPid(),
                Process.myUid());
        if (PackageManager.PERMISSION_GRANTED == status) {
            return true;
        }

        return false;
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    private void takePhoto() {
        if (null != mAcc) {
            mAcc.start();
        }

        mStopTrack = false;
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!mStopTrack) {
                    if (null == nv21) {
                        continue;
                    }

                    synchronized (nv21) {
                        System.arraycopy(nv21, 0, buffer,
                                0, nv21.length);
                    }

                    // 获取手机朝向，返回值0,1,2,3分别表示0,90,180和270度
                    int direction = Accelerometer.getDirection();

                    boolean frontCamera = (CameraInfo.CAMERA_FACING_FRONT == mCameraId);
                    // 前置摄像头预览显示的是镜像，需要将手机朝向换算成摄相头视角下的朝向。
                    // 转换公式：a' = (360 - a)%360，a为人眼视角下的朝向（单位：角度）
                    if (frontCamera) {
                        // SDK中使用0,1,2,3,4分别表示0,90,180,270和360度
                        direction = (4 - direction) % 4;
                    }

                    if (mFaceDetector == null) {
                        /**
                         * 离线视频流检测功能需要单独下载支
                         持离线人脸的SDK
                         * 请开发者前往语音云官网下载对应
                         SDK
                         */
                        showTip("本SDK不支持离线视频流检测");
                        break;
                    }

                    String result = mFaceDetector.trackNV21
                            (buffer, PREVIEW_WIDTH, PREVIEW_HEIGHT, isAlign, direction);
                    Log.d(TAG, "result:" + result);

                    FaceRect[] faces = ParseResult.parseResult
                            (result);

                    Canvas canvas = mFaceSurface.getHolder
                            ().lockCanvas();
                    if (null == canvas) {
                        continue;
                    }

                    canvas.drawColor(0, PorterDuff.Mode.CLEAR);
                    canvas.setMatrix(mScaleMatrix);

                    if (faces.length <= 0) {
                        mFaceSurface.getHolder
                                ().unlockCanvasAndPost(canvas);
                        continue;
                    }

                    if (null != faces && frontCamera ==
                            (CameraInfo.CAMERA_FACING_FRONT == mCameraId)) {
                        for (FaceRect face : faces) {
                            face.bound =
                                    FaceUtil.RotateDeg90(face.bound, PREVIEW_WIDTH, PREVIEW_HEIGHT);
                            if (face.point != null) {
                                for (int i = 0; i <
                                        face.point.length; i++) {
                                    face.point
                                            [i] = FaceUtil.RotateDeg90(face.point[i], PREVIEW_WIDTH, PREVIEW_HEIGHT);
                                }
                            }
                            //有人脸

                            FaceUtil.drawFaceRect
                                    (canvas, face, PREVIEW_WIDTH, PREVIEW_HEIGHT,

                                            frontCamera, false);
                            if (safeToTakePicture) {
                                //开始拍照
                                mCamera.takePicture(null, null, mPicture);
                                safeToTakePicture = false;
                            }
                        }
                    } else {
                        Log.d(TAG, "faces:0");
                    }

                    mFaceSurface.getHolder().unlockCanvasAndPost(canvas);
                }
            }
        }).start();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (null != mAcc) {
            mAcc.stop();
        }
        mStopTrack = true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        closeCamera();
        // 销毁对象
        mFaceDetector.destroy();
    }

    private void showTip(final String str) {
        mToast.setText(str);
        mToast.show();
    }

    //拍照监听
    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {


        //拍照会调用此方法
        //data:照片的字节数组
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.i(TAG, "onPictureTaken: >>>>>>>>>>>>>>>>>>>>");
            safeToTakePicture = true;
            int startType = 0;
            try {
                File file = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                File pictureFile = new File(file, "alarmphoto.jpg");

                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();

                Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());
                Bitmap newBitmap = FaceUtil.rotateImage(270, bitmap);

                FaceUtil.saveBitmapToNewFile(VideoDemo.this, newBitmap, pictureFile.getPath());


                Intent intent = getIntent();
                startType = intent.getIntExtra("startType", -1);


                if (startType == FACE_VERIFY) {

                    //保存拍照路径
                    Intent intentResult = new Intent();
                    intentResult.putExtra("file", pictureFile.getAbsolutePath());
                    setResult(FACE_VERIFY_RESULT, intentResult);
                }

            } catch (FileNotFoundException e) {
                Log.d("camers", "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d("camers", "Error accessing file: " + e.getMessage());
            } finally {

                safeToTakePicture = true;
                if (startType == 1) {
                    finish();
                } else {
                    //拍照完成后重新进入预览
                    camera.startPreview();
                }

            }
        }
    };

//
//	/**
//	 * 拍照完成上传照片
//	 */
//	public void uploadPhoto() {
//		sp = getSharedPreferences("data", MODE_PRIVATE);
//		String  facilityId = sp.getString("facilityId","");
//		String uploadPath = "http://api.heclouds.com/bindata?device_id=" + facilityId + "&datastream_id=camera";
//		AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
//
//		Header[] headers = {new BasicHeader("api-key", "bLkMpnNyrTYsRnn=3Mt0MkyUH1g=")};
//		File photo = new File("/storage/sdcard0/alarmphoto.jpg");
//		HttpEntity entity = new FileEntity(photo, null);
//		asyncHttpClient.post(this, uploadPath, headers, entity, "multipart/form-data ", new AsyncHttpResponseHandler() {
//			@Override
//			public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
//				String body = new String(responseBody);
//				try {
//					//回馈信息
//					JSONObject jsonObject = new JSONObject(body);
//					JSONObject jsonData = (JSONObject) jsonObject.get("data");
//					String index = (String) jsonData.get("index");
//					//将上传的照片Id放入JSon中的cameras
//					String cameras = "";
//					if(alarm.getCamera().length() == 2){
//						cameras = alarm.getCamera().replace("]", "") + index + "]";
//					}else{
//						cameras = alarm.getCamera().replace("]", ",") + index + "]";
//					}
//					//拼接jsonStirng
//					JSONObject jsonObject1 = new JSONObject();
//					jsonObject1.put("email",alarm.getAlarmEmail());
//					jsonObject1.put("className",className);
//					jsonObject1.put("errorCode",alarm.getErrorCode());
//					jsonObject1.put("camera",cameras);
//
//
//
//					System.out.println(jsonObject1.toString());
//					 resultJson(ip, jsonObject1.toString());
//
//				} catch (JSONException e) {
//					e.printStackTrace();
//				}
//
//			}
//
//			@Override
//			public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
//
//			}
//		});
//
//	}
//
//	/**
//	 * 回馈信息，将上传照片的Id发送给服务器
//	 * @param ip
//	 * @param jsonString
//	 */
//	public void resultJson(String ip, String jsonString) {
//
//		final String path = "http://" + ip + ":8080/smartlink/sendEmail";
//		final AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
//		RequestParams requestParams = new RequestParams();
//		requestParams.put("info", jsonString);
//		asyncHttpClient.post(path, requestParams, new AsyncHttpResponseHandler() {
//
//			@Override
//			public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
//
//				asyncHttpClient.post(path, new AsyncHttpResponseHandler() {
//					@Override
//					public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
//
//					}
//
//					@Override
//					public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
//
//					}
//				});
//			}
//
//			@Override
//			public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
//
//			}
//		});
//
//
//	}


}
